package com.chcit.mobile.helper;

import androidx.annotation.NonNull;
import com.chcit.mobile.common.SPDErrorHandle;
import com.chcit.mobile.mvp.common.api.service.UserService;
import com.jess.arms.base.app.Quick;
import com.jess.arms.di.component.AppComponent;
import com.jess.arms.utils.ArmsUtils;
import com.vector.update_app.HttpManager;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Map;
import io.reactivex.Observable;
import io.reactivex.Observer;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.disposables.Disposable;
import io.reactivex.schedulers.Schedulers;
import okhttp3.ResponseBody;


/**
 * Created by Vector
 * on 2017/6/19 0019.
 */

public class UpdateAppHttpUtil implements HttpManager {


    /*public UpdateAppHttpUtil(IRepositoryManager repositoryManager){
        mIRepositoryManager = repositoryManager;
    }*/
    /**
     * 异步get
     *
     * @param url      get请求地址
     * @param params   get参数
     * @param callBack 回调
     */
    @Override
    public void asyncGet(@NonNull String url, @NonNull Map<String, String> params, @NonNull final Callback callBack) {
        ArmsUtils.obtainAppComponentFromContext(Quick.getApplicationContext()).repositoryManager().obtainRetrofitService(UserService.class)
                .update(url+"#url_ignore")
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new Observer<String>() {
                    @Override
                    public void onSubscribe(Disposable d) {

                    }

                    @Override
                    public void onNext(String responseBody) {
                        callBack.onResponse(responseBody);
                    }

                    @Override
                    public void onError(Throwable e) {
                        callBack.onError(e.getMessage());
                    }

                    @Override
                    public void onComplete() {

                    }


                })
              //  .subscribeOn((Schedulers.io())

              ;


      /*  OkHttpUtils.get()
                .url(url)
                .params(params)
                .build()
                .execute(new StringCallback() {
                    @Override
                    public void onError(Call call, Response response, Exception e, int id) {
                        callBack.onError(validateError(e, response));
                    }

                    @Override
                    public void onResponse(String response, int id) {
                        callBack.onResponse(response);
                    }
                });*/
    }

    /**
     * 异步post
     *
     * @param url      post请求地址
     * @param params   post请求参数
     * @param callBack 回调
     */
    @Override
    public void asyncPost(@NonNull String url, @NonNull Map<String, String> params, @NonNull final Callback callBack) {


    }

    /**
     * 下载
     *
     * @param url      下载地址
     * @param path     文件保存路径
     * @param fileName 文件名称
     * @param callback 回调
     */
    private String url;
    @Override
    public void download(@NonNull String url, @NonNull String path, @NonNull String fileName, @NonNull final FileCallback callback) {
       /* FileDownLoadObserver<File> fileDownLoadObserver = new FileDownLoadObserver<File>() {
            @Override
            public void onDownLoadSuccess(File o) {
                callback.onResponse(o);
            }

            @Override
            public void onDownLoadFail(Throwable throwable) {

            }

            @Override
            public void onProgress(int progress, long total) {

            }
        };*/
        AppComponent appComponent = ArmsUtils.obtainAppComponentFromContext(Quick.getApplicationContext());
//        if(this.url == null||!this.url.equals(url)){
//            this.url = url;
//            ProgressManager.getInstance().addResponseListener(RetrofitUrlManager.getInstance().getBaseUrl().toString()+url, new ProgressListener() {
//                @Override
//                public void onProgress(ProgressInfo progressInfo) {
//                    callback.onProgress((BigDecimal.valueOf(progressInfo.getPercent()).divide(BigDecimal.valueOf(100)).floatValue()),progressInfo.getContentLength());
//                }
//
//                @Override
//                public void onError(long id, Exception e) {
//                    callback.onError(e.getMessage());
//                }
//            });
//        }


        appComponent.repositoryManager().obtainRetrofitService(UserService.class)
                .down(url)
                .subscribeOn(Schedulers.io())
                .map(responseBody -> saveFile(responseBody,path,fileName,callback))
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new SPDErrorHandle<File>(appComponent.rxErrorHandler()){
                    @Override
                    public void onSubscribe(Disposable d) {
                        super.onSubscribe(d);
                        callback.onBefore();
                    }


                    @Override
                    public void onNext(File file) {
                        callback.onResponse(file);
                    }

                });



       /* OkHttpUtils.get()
                .url(url)
                .build()
                .execute(new FileCallBack(path, fileName) {
                    @Override
                    public void inProgress(float progress, long total, int id) {
                        callback.onProgress(progress, total);
                    }

                    @Override
                    public void onError(Call call, Response response, Exception e, int id) {
                        callback.onError(validateError(e, response));
                    }

                    @Override
                    public void onResponse(File response, int id) {
                        callback.onResponse(response);

                    }

                    @Override
                    public void onBefore(Request request, int id) {
                        super.onBefore(request, id);
                        callback.onBefore();
                    }
                });*/

    }
    private File saveFile(ResponseBody responseBody, String destFileDir, String destFileName,final FileCallback callback) throws IOException {

        InputStream is = null;
        byte[] buf = new byte[2048];
        int len = 0;
        FileOutputStream fos = null;
        Disposable disposable = null;
        try {
            is = responseBody.byteStream();
            final long total = responseBody.contentLength();
            long sum = 0;

            File dir = new File(destFileDir);
            if (!dir.exists()) {
                if(!dir.mkdirs()){
                    throw new IOException("创建目录失败！");
                }
            }
            File file = new File(dir, destFileName);
            fos = new FileOutputStream(file);
            float preProgress = 0;
            while ((len = is.read(buf)) != -1) {
                sum += len;
                fos.write(buf, 0, len);
                //final long finalSum = sum;
                //这里就是对进度的监听回调
                float progress = (float)sum/(float)total;
                if(progress-preProgress > 0.01f){
                    preProgress = progress;
                    disposable = Observable.just(progress)
                            .subscribeOn(AndroidSchedulers.mainThread())
                            .subscribe( (o) -> {
                                callback.onProgress(o,total);
                            });
                }
            }
            fos.flush();
            return file;

        } finally {
            try {
                if (is != null) is.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
            try {
                if (fos != null) fos.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
            if(disposable!=null){
                disposable.dispose();
            }
        }
    }
}